home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / sound / 2608intf.c < prev    next >
C/C++ Source or Header  |  2000-05-21  |  8KB  |  322 lines

  1. /* don't support sampling rythm sound yet */
  2. //#define YM2608_USE_SAMPLES
  3. /***************************************************************************
  4.  
  5.   2608intf.c
  6.  
  7.   The YM2608 emulator supports up to 2 chips.
  8.   Each chip has the following connections:
  9.   - Status Read / Control Write A
  10.   - Port Read / Data Write A
  11.   - Control Write B
  12.   - Data Write B
  13.  
  14. ***************************************************************************/
  15.  
  16. #include "driver.h"
  17. #include "ay8910.h"
  18. #include "2608intf.h"
  19. #include "fm.h"
  20.  
  21. #ifdef BUILD_YM2608
  22.  
  23. /* use FM.C with stream system */
  24.  
  25. static int stream[MAX_2608];
  26.  
  27. static signed short *rhythm_buf;
  28.  
  29. /* Global Interface holder */
  30. static const struct YM2608interface *intf;
  31.  
  32. static void *Timer[MAX_2608][2];
  33.  
  34. #ifdef YM2608_USE_SAMPLES
  35. static const char *ym2608_pDrumNames[] =
  36. {
  37.     "2608_BD.wav",
  38.     "2608_SD.wav",
  39.     "2608_TOP.wav",
  40.     "2608_HH.wav",
  41.     "2608_TOM.wav",
  42.     "2608_RIM.wav",
  43.     0
  44. };
  45. #endif
  46.  
  47. /*------------------------- TM2608 -------------------------------*/
  48. /* IRQ Handler */
  49. static void IRQHandler(int n,int irq)
  50. {
  51.     if(intf->handler[n]) intf->handler[n](irq);
  52. }
  53.  
  54. /* Timer overflow callback from timer.c */
  55. static void timer_callback_2608(int param)
  56. {
  57.     int n=param&0x7f;
  58.     int c=param>>7;
  59.  
  60. //    logerror("2608 TimerOver %d\n",c);
  61.     Timer[n][c] = 0;
  62.     YM2608TimerOver(n,c);
  63. }
  64.  
  65. /* TimerHandler from fm.c */
  66. static void TimerHandler(int n,int c,int count,double stepTime)
  67. {
  68.     if( count == 0 )
  69.     {    /* Reset FM Timer */
  70.         if( Timer[n][c] )
  71.         {
  72. //            logerror("2608 TimerReset %d\n",c);
  73.              timer_remove (Timer[n][c]);
  74.             Timer[n][c] = 0;
  75.         }
  76.     }
  77.     else
  78.     {    /* Start FM Timer */
  79.         double timeSec = (double)count * stepTime;
  80.  
  81.         if( Timer[n][c] == 0 )
  82.         {
  83.             Timer[n][c] = timer_set (timeSec , (c<<7)|n, timer_callback_2608 );
  84.         }
  85.     }
  86. }
  87.  
  88. static void FMTimerInit( void )
  89. {
  90.     int i;
  91.  
  92.     for( i = 0 ; i < MAX_2608 ; i++ )
  93.         Timer[i][0] = Timer[i][1] = 0;
  94. }
  95.  
  96. /* update request from fm.c */
  97. void YM2608UpdateRequest(int chip)
  98. {
  99.     stream_update(stream[chip],100);
  100. }
  101.  
  102. int YM2608_sh_start(const struct MachineSound *msound)
  103. {
  104.     int i,j;
  105.     int rate = Machine->sample_rate;
  106.     char buf[YM2608_NUMBUF][40];
  107.     const char *name[YM2608_NUMBUF];
  108.     int mixed_vol,vol[YM2608_NUMBUF];
  109.     void *pcmbufa[YM2608_NUMBUF];
  110.     int  pcmsizea[YM2608_NUMBUF];
  111.     int rhythm_pos[6+1];
  112.     struct GameSamples    *psSamples;
  113.     int total_size,r_offset,s_size;
  114.  
  115.     intf = msound->sound_interface;
  116.     if( intf->num > MAX_2608 ) return 1;
  117.  
  118.     if (AY8910_sh_start(msound)) return 1;
  119.  
  120.     /* Timer Handler set */
  121.     FMTimerInit();
  122.  
  123.     /* stream system initialize */
  124.     for (i = 0;i < intf->num;i++)
  125.     {
  126.         /* stream setup */
  127.         mixed_vol = intf->volumeFM[i];
  128.         /* stream setup */
  129.         for (j = 0 ; j < YM2608_NUMBUF ; j++)
  130.         {
  131.             name[j]=buf[j];
  132.             vol[j] = mixed_vol & 0xffff;
  133.             mixed_vol>>=16;
  134.             sprintf(buf[j],"%s #%d Ch%d",sound_name(msound),i,j+1);
  135.         }
  136.         stream[i] = stream_init_multi(YM2608_NUMBUF,name,vol,rate,i,YM2608UpdateOne);
  137.         /* setup adpcm buffers */
  138.         pcmbufa[i]  = (void *)(memory_region(intf->pcmrom[i]));
  139.         pcmsizea[i] = memory_region_length(intf->pcmrom[i]);
  140.     }
  141.  
  142.     /* rythm rom build */
  143.     rhythm_buf = 0;
  144. #ifdef YM2608_USE_SAMPLES
  145.     psSamples = readsamples(ym2608_pDrumNames,"ym2608");
  146. #else
  147.     psSamples = 0;
  148. #endif
  149.     if( psSamples )
  150.     {
  151.         /* calcrate total data size */
  152.         total_size = 0;
  153.         for( i=0;i<6;i++)
  154.         {
  155.             s_size = psSamples->sample[i]->length;
  156.             total_size += s_size ? s_size : 1;
  157.         }
  158.         /* aloocate rythm data */
  159.         rhythm_buf = malloc(total_size * sizeof(signed short));
  160.         if( rhythm_buf==0 ) return 0;
  161.  
  162.         r_offset = 0;
  163.         /* merge sampling data */
  164.         for(i=0;i<6;i++)
  165.         {
  166.             /* set start point */
  167.             rhythm_pos[i] = r_offset*2;
  168.             /* copy sample data */
  169.             s_size = psSamples->sample[i]->length;
  170.             if(s_size && psSamples->sample[i]->data)
  171.             {
  172.                 if( psSamples->sample[i]->resolution==16 )
  173.                 {
  174.                     signed short *s_ptr = (signed short *)psSamples->sample[i]->data;
  175.                     for(j=0;j<s_size;j++) rhythm_buf[r_offset++] = *s_ptr++;
  176.                 }else{
  177.                     signed char *s_ptr = (signed char *)psSamples->sample[i]->data;
  178.                     for(j=0;j<s_size;j++) rhythm_buf[r_offset++] = (*s_ptr++)*0x0101;
  179.                 }
  180.             }else rhythm_buf[r_offset++] = 0;
  181.             /* set end point */
  182.             rhythm_pos[i+1] = r_offset*2;
  183.         }
  184.         freesamples( psSamples );
  185.     }else
  186.     {
  187.         /* aloocate rythm data */
  188.         rhythm_buf = malloc(6 * sizeof(signed short));
  189.         if( rhythm_buf==0 ) return 0;
  190.         for(i=0;i<6;i++)
  191.         {
  192.             /* set start point */
  193.             rhythm_pos[i] = i*2;
  194.             rhythm_buf[i] = 0;
  195.             /* set end point */
  196.             rhythm_pos[i+1] = (i+1)*2;
  197.         }
  198.     }
  199.  
  200.     /**** initialize YM2608 ****/
  201.     if (YM2608Init(intf->num,intf->baseclock,rate,
  202.                    pcmbufa,pcmsizea,rhythm_buf,rhythm_pos,
  203.                    TimerHandler,IRQHandler) == 0)
  204.         return 0;
  205.  
  206.     /* error */
  207.     return 1;
  208. }
  209.  
  210. /************************************************/
  211. /* Sound Hardware Stop                            */
  212. /************************************************/
  213. void YM2608_sh_stop(void)
  214. {
  215.     YM2608Shutdown();
  216.     if( rhythm_buf ) free(rhythm_buf);
  217.     rhythm_buf = 0;
  218. }
  219. /* reset */
  220. void YM2608_sh_reset(void)
  221. {
  222.     int i;
  223.  
  224.     for (i = 0;i < intf->num;i++)
  225.         YM2608ResetChip(i);
  226. }
  227.  
  228. /************************************************/
  229. /* Status Read for YM2608 - Chip 0                */
  230. /************************************************/
  231. READ_HANDLER( YM2608_status_port_0_A_r )
  232. {
  233. //logerror("PC %04x: 2608 S0A=%02X\n",cpu_get_pc(),YM2608Read(0,0));
  234.     return YM2608Read(0,0);
  235. }
  236.  
  237. READ_HANDLER( YM2608_status_port_0_B_r )
  238. {
  239. //logerror("PC %04x: 2608 S0B=%02X\n",cpu_get_pc(),YM2608Read(0,2));
  240.     return YM2608Read(0,2);
  241. }
  242.  
  243. /************************************************/
  244. /* Status Read for YM2608 - Chip 1                */
  245. /************************************************/
  246. READ_HANDLER( YM2608_status_port_1_A_r ) {
  247.     return YM2608Read(1,0);
  248. }
  249.  
  250. READ_HANDLER( YM2608_status_port_1_B_r ) {
  251.     return YM2608Read(1,2);
  252. }
  253.  
  254. /************************************************/
  255. /* Port Read for YM2608 - Chip 0                */
  256. /************************************************/
  257. READ_HANDLER( YM2608_read_port_0_r ){
  258.     return YM2608Read(0,1);
  259. }
  260.  
  261. /************************************************/
  262. /* Port Read for YM2608 - Chip 1                */
  263. /************************************************/
  264. READ_HANDLER( YM2608_read_port_1_r ){
  265.     return YM2608Read(1,1);
  266. }
  267.  
  268. /************************************************/
  269. /* Control Write for YM2608 - Chip 0            */
  270. /* Consists of 2 addresses                        */
  271. /************************************************/
  272. WRITE_HANDLER( YM2608_control_port_0_A_w )
  273. {
  274.     YM2608Write(0,0,data);
  275. }
  276.  
  277. WRITE_HANDLER( YM2608_control_port_0_B_w )
  278. {
  279.     YM2608Write(0,2,data);
  280. }
  281.  
  282. /************************************************/
  283. /* Control Write for YM2608 - Chip 1            */
  284. /* Consists of 2 addresses                        */
  285. /************************************************/
  286. WRITE_HANDLER( YM2608_control_port_1_A_w ){
  287.     YM2608Write(1,0,data);
  288. }
  289.  
  290. WRITE_HANDLER( YM2608_control_port_1_B_w ){
  291.     YM2608Write(1,2,data);
  292. }
  293.  
  294. /************************************************/
  295. /* Data Write for YM2608 - Chip 0                */
  296. /* Consists of 2 addresses                        */
  297. /************************************************/
  298. WRITE_HANDLER( YM2608_data_port_0_A_w )
  299. {
  300.     YM2608Write(0,1,data);
  301. }
  302.  
  303. WRITE_HANDLER( YM2608_data_port_0_B_w )
  304. {
  305.     YM2608Write(0,3,data);
  306. }
  307.  
  308. /************************************************/
  309. /* Data Write for YM2608 - Chip 1                */
  310. /* Consists of 2 addresses                        */
  311. /************************************************/
  312. WRITE_HANDLER( YM2608_data_port_1_A_w ){
  313.     YM2608Write(1,1,data);
  314. }
  315. WRITE_HANDLER( YM2608_data_port_1_B_w ){
  316.     YM2608Write(1,3,data);
  317. }
  318.  
  319. /**************** end of file ****************/
  320.  
  321. #endif
  322.